package com.mingda.weathermagiccenter.utils;


import com.mingda.weathermagiccenter.config.LegendTemConfig;
import com.mingda.weathermagiccenter.config.hefengconfig.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Service
public class WeatherDeal {


    @Autowired
    private WeatherConfigBean configBean;

    //调用将图例数据一并返回给前端
    public Map getPrecRange(List<HashMap> list){
        Map map = new HashMap();
        if(list.size()>0) {
            map.put("legendprec",configBean.getLegendprec());
            map.put("legendprec10days",configBean.getLegendprec10days());
            map.put("legendprec3months",configBean.getLegendprec3months());
            map.put("legendprecall", configBean.getLegendprecall());
        }
        map.put("data",list);
        return map;
    }

    //调用将图例数据一并返回给前端
    public Map getRange(List<HashMap> list){
         Map map = new HashMap();
         if(list.size()>0) {
             map.put("legendtem", calculateRange(list,configBean.getLegendtem()));
             map.put("legendtemall", configBean.getLegendtem());
             map.put("legendwind", configBean.getLegendwind());
             map.put("legendprec",configBean.getLegendprec());
             map.put("legendhumi",configBean.getLegendhumi());
             map.put("legendpres",configBean.getLegendpres());
             map.put("legendwaterrate",configBean.getLegendwaterrate());
             map.put("legendwaterrateout",configBean.getLegendwaterrateout());
             map.put("legendwaterrateinside",configBean.getLegendwaterrateinside());
             map.put("legendprecall", configBean.getLegendprecall());

         }
         map.put("data",list);
        return map;
    }

   public <T> List<LegendTemConfig> calculateRange(List<HashMap> list, List<LegendTemConfig> config){
        List<LegendTemConfig> legendTemConfigs = configBean.getLegendtem();
        Optional<Float> mintemp =  list.stream().map(obj -> (Float)obj.get("temp")).filter(temp -> temp != null && (temp instanceof Float) && temp < 50.0f).min(Float::compareTo);
        Optional<Float> maxtemp =  list.stream().map(obj -> (Float)obj.get("temp")).filter(temp -> temp != null && (temp instanceof Float) && temp < 50.0f).max(Float::compareTo);
        // float range = (maxtemp - mintemp) / legendTemConfigs.size();
        List<LegendTemConfig> result = generateBands(mintemp.get(),maxtemp.get(),config);
        return  result;
    }




    public static  List<LegendTemConfig> generateBands(float minTemp, float maxTemp, List<LegendTemConfig> configs) {
        List<LegendTemConfig>   list = new ArrayList<LegendTemConfig>();
        for (int i = 0; i < configs.size(); i++) {
            if(configs.get(i).getValue() >= minTemp - 2 && configs.get(i).getValue() <= maxTemp + 2 ){
                list.add(configs.get(i));
            }
        }
        return list;


        /*maxTemp = maxTemp + 0.5f;
        minTemp = minTemp - 0.5f;
        //计算每个温度带的范围  掐头去尾
        float range = (maxTemp - minTemp) /( configs.size() - 1); //确保10个段
        // 定义颜色数组，可以根据需要自定义 String[] colors = { "#FF0000",
        // 红色 "#FF7F00", // 橙色 "#FFFF00", // 黄色 "#7FFF00", // 浅绿色 "#00FF00", //绿色 "#00FFFF", // 青色 "#007FFF", // 浅蓝色 "#0000FF", // 蓝色 "#7F00FF", // 紫色 "#FF00FF" // 粉色 };
        for (int i = 0; i < configs.size(); i++) {
                BigDecimal bd = BigDecimal.valueOf(minTemp + (i * range)).setScale(1, RoundingMode.HALF_UP);
                ((configs.get(i))).setValue(bd.floatValue());
        }
        return configs;
         */
    }



        //这个方法是自定义方法用于计算火险等级并且返回
    public List<HashMap> getFireLevel(List<HashMap> list){
        SimpleDateFormat sdfresult = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
        SimpleDateFormat ymd = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat md = new SimpleDateFormat("MM-dd");
        //挨个计算
        for(HashMap s : list ){

            //开始计算火险指数
            // U = f(V) + f(T) + f(R) + f(M) ;
            int v = calculateWindSpeed(s);   //风速指数
            int t = calculateTemperature(s); //温度指数
            int r = calculateHumidity(s);    //湿度指数
            int m = calculateNoRainDay(s);   //干旱指数
            int u = v + t + r + m; //总体指数
            //如果下雨了
            int c = 1;

            try {
                if (s.get("norainday") != null && (Integer) s.get("norainday") == 0) {
                    c = 0;
                }
            }
            catch (Exception e){

            }

            //春防期间
            int c1 = 0;
            //日期  月日格式用于判断防火期
            String mdstr = null;
            try {
                LocalDateTime localDateTime = (LocalDateTime)s.get("timeBase");
                mdstr = localDateTime.format(DateTimeFormatter.ofPattern("MM-dd"));
                if (configBean.getSpring_prevention_start().compareTo(mdstr) <= 0 && configBean.getSpring_prevention_end().compareTo(mdstr) >= 0) {
                    c1 = 1;
                } else if (configBean.getAutumn_prevention_start().compareTo(mdstr) <= 0 && configBean.getAutumn_prevention_end().compareTo(mdstr) >= 0) {
                    c1 = 1;
                }
            } catch (Exception e) {

            }

            s.put("ffid",u + " = " + v + " + " + t + " + " + r + " + " + m + " C降雨指数=" + c + " C1春防秋防指数=" + c1);
            //最终ffdi 指数
            u = u * c * c1;
            //带入公式计算火险等级
            //带入公式计算火险等级
            s.put("firelevel",calculateFireLevel(u));
        }
        return list;
    }


    /**
     * 通过指数计算火险等级
     */
    public String calculateFireLevel(int ffdi){
        String result  = "1";  //默认一级火险
        List<FireLevelConfig> list = configBean.getFirelevel();
        try{
            for(FireLevelConfig  fireLevelConfig : list){
                if(fireLevelConfig.getMinffdr() <= ffdi && fireLevelConfig.getMaxffdr() > ffdi ){
                    result = fireLevelConfig.getLevel();
                    break;
                }
            }
        }
        catch (Exception e){
        }
        return result;
    }

    /**
     * 通过风速计算指数
     * @param weather
     * @return
     */
  public int calculateWindSpeed(HashMap weather){
        int result = 0;
        float windspeed = 0;
        List<WindSpeedConfig> list = configBean.getWindspeed();
        try{
            windspeed =  (Float) weather.get("win_10_vel") ;
            for(WindSpeedConfig  windSpeedConfig : list){
                if(windSpeedConfig.getMin() < windspeed && windSpeedConfig.getMax() >= windspeed ){
                    result = windSpeedConfig.getGrad();
                    break;
                }
            }
        }
        catch (Exception e){
            e.printStackTrace();
        }
        return result;
    }



    public int calculateTemperature(HashMap weather){
        int result = 0;
        float temperature = 0;
        List<TemperatureConfig> list = configBean.getTemperature();
        try{
            //温度取14时温度
            try {
                temperature = (Float) weather.get("temp_max");
            }
            catch (Exception e){
                temperature = (Float) weather.get("temp");
            }
            for(TemperatureConfig  temperatureConfig : list){
                if(temperatureConfig.getMin() < temperature && temperatureConfig.getMax() >= temperature ){
                    result = temperatureConfig.getGrad();
                    break;
                }
            }
        }
        catch (Exception e){
            e.printStackTrace();
        }
        return result;
    }


    public int calculateHumidity(HashMap weather){
        int result = 0;
        float humidity = 0;
        List<HumidityConfig> list = configBean.getHumidity();
        try{
            //温度取14时温度
            humidity =  (Float) weather.get("humi");
            for(HumidityConfig  humidityConfig : list){
                if(humidityConfig.getMin() <= humidity && humidityConfig.getMax() > humidity ){
                    result = humidityConfig.getGrad();
                    break;
                }
            }
        }
        catch (Exception e){
            e.printStackTrace();
        }
        return result;
    }


    public int calculateNoRainDay(HashMap weather){
        int result = 0;
        long norainday = 0;
        List<NoraindayConfig> list = configBean.getNorainday();
        try{
            //温度取14时温度
            //norainday =   weather.get("norainday");

            norainday = (long)(Double.parseDouble(weather.get("norainday").toString()));

            for(NoraindayConfig  noraindayConfig : list){
                if(noraindayConfig.getMin() <= norainday && noraindayConfig.getMax() >= norainday ){
                    result = noraindayConfig.getGrad();
                    break;
                }
            }
        }
        catch (Exception e){
            e.printStackTrace();
        }
        return result;
    }


}
